package com.onesports.intelligent.k12.polarlight.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.onesports.intelligent.k12.polarlight.common.constant.HeaderConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author aj
 * @author: xiong pengfei
 */
public class JsonAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private boolean postOnly = true;

    /**
     * 项目启动时调用：设置登录请求地址
     */
    public JsonAuthenticationFilter() {
    }

    /**
     * 调用登录接口时调用该方法
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        String clientCode = request.getHeader(HeaderConstants.ORIGIN_CLIENT_CODE);
        if (this.postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        if (StringUtils.isBlank(clientCode)) {
            throw new AuthenticationServiceException("Origin-Client-Code can not be null");
        }
        // 判断 ContentType 类型
        if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType())
                || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(request.getContentType())) {
            ObjectMapper mapper = new ObjectMapper();
            try {
                Map<String, String> authenticationBean = mapper.readValue(request.getInputStream(), Map.class);
                String usernameAndOrigin = String.format("%s%s%s", authenticationBean.get(SPRING_SECURITY_FORM_USERNAME_KEY),
                        "-", clientCode);
                UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                        usernameAndOrigin, authenticationBean.get(SPRING_SECURITY_FORM_PASSWORD_KEY));
                setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                throw new AuthenticationServiceException("IO Exception");
            }
        } else {
            // 兼容表单登陆
            throw new AuthenticationServiceException("Authentication 'Content-Type' not supported");
//            return super.attemptAuthentication(request, response);
        }
    }
}
